package fserv.fileshare;

import java.io.*;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import fserv.control.ClientController;

/**
 * File share module: File Sender.
 * 
 * Launches a thread and sends a local file to a remote peer who has established
 * a connection with a FileListener.
 * 
 * @author Arthur Bit-Monnot <abit@etud.insa-toulouse.fr>
 * @author Julien Marchand <jmarchan@etud.insa-toulouse.fr>
 */
class FileSender extends Thread {
    
    /**
     * Reference to the Chat Controller.
     */
    private ClientController ctrl;
    
    /**
     * Local file to send.
     */
    private File file;
    
    /**
     * Socket used to send the file to the remote peer.
     */
    private Socket clientSocket;
    
    public FileSender(ClientController ctrl, File file, Socket clientSocket) {
        this.ctrl = ctrl;
        this.file = file;
        this.clientSocket = clientSocket;
    }
    
    /**
     * Sends a local file to a remote peer using a connection accept()ed
     * in a FileListener.
     */
    @Override
    public void run() {
        Logger.getLogger(FileSender.class.getName()).log(Level.INFO, "Starting.");
        
        ctrl.fileShareUploadStarted(file, clientSocket.getInetAddress());
        
        BufferedInputStream bis = null;
        try {
            OutputStream os = clientSocket.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[clientSocket.getSendBufferSize()];
            int read;
            while ((read = bis.read(buffer)) != -1) {
                os.write(buffer, 0, read);
            }
            ctrl.fileShareUploadFinished(file, clientSocket.getInetAddress());
        } catch (FileNotFoundException ex) {
            Logger.getLogger(FileSender.class.getName()).log(Level.SEVERE, null, ex);
            ctrl.fileShareUploadFailed(file, clientSocket.getInetAddress());
        } catch (IOException ex) {
            Logger.getLogger(FileSender.class.getName()).log(Level.SEVERE, null, ex);
            ctrl.fileShareUploadFailed(file, clientSocket.getInetAddress());
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException ex) {
                Logger.getLogger(FileSender.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                if (bis != null) {
                    clientSocket.close();
                }
            } catch (IOException ex) {
                Logger.getLogger(FileSender.class.getName()).log(Level.SEVERE, null, ex);
            }            
        }
        
        Logger.getLogger(FileSender.class.getName()).log(Level.INFO, "Exiting.");
    }
}
